home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-12-16 | 46.9 KB | 1,714 lines |
- Newsgroups: comp.sources.misc
- X-UNIX-From: gwr@linus.mitre.org
- keywords: fdisk partition boot menu bootmenu pfdisk
- organization: The MITRE Corporation, Bedford, MA.
- summary: primary boot sector program with menu
- subject: v15i084: BOOTMENU and PFDISK 1.3 (part 1/2)
- from: gwr@linus.mitre.org
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 15, Issue 84
- Submitted-by: gwr@linus.mitre.org
- Archive-name: bootmenu/part01
-
- Here is part 1 of the BOOTMENU and PFDISK 1.3 distribution.
-
- BOOTMENU is a replacement primary boot sector for MS-DOS compatible
- machines which allows boot-time selection of the active hard disk
- partition using a menu. For example, users with both UNIX and DOS
- on their hard disk can choose which system to use at boot time.
-
- PFDISK is a replacement "fdisk" command for
- installing BOOTMENU without clobbering your partition table.
-
- See the README file at the beginning of the shell archive below for a
- general description of this package. Program documentation for both
- BOOTMENU and PFDISK are at the beginning of the second posting.
-
- Gordon W. Ross (M/S E095) internet: gwr@linus.mitre.org
- The MITRE Corporation uucp: {decvax|philabs}!linus!gwr
- Burlington Road office phone: 617-271-3205
- Bedford, MA 01730 (U.S.A.)
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # README
- # pfdisk.man
- # Changes
- # Makefile
- # pfdisk.c
- # syscodes.c
- # syscodes.h
- # sysdep.h
- # s_esix.c
- # s_i386.c
- # s_unix.c
- # s_msdos.c
- # This archive created: Tue Oct 23 13:53:17 1990
- # By: Gordon W. Ross (The MITRE Corporation, Bedford, MA.)
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'README'" '(3148 characters)'
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- cat << \SHAR_EOF > 'README'
-
- BOOTMENU is a replacement primary boot sector for MS-DOS compatible
- machines which allows boot-time selection of the active hard disk
- partition using a menu. For example, users with both UNIX and DOS
- on their hard disk can choose which system to use at boot time.
-
- BOOTAUTO is similar to BOOTMENU but allows both unattended reboot
- and the ability to override the automatic selection of the active
- partition at boot-time. (I used to call this version boot-hdp).
-
- BOOTMENU cannot do an unattended reboot but is very small and
- (as a result) will not be clobbered if you use the SpeedStor
- disk formatting/diagnostics program. (Notes about SpeedStor's
- usage of the primary boot sector are in the file SStor.txt).
-
- PFDISK is a replacement for both DOS and UNIX fdisk programs.
- This replacement is distinguished for its ability to put
- an arbitrary binary image into the primary boot sector without
- clobbering an existing partition table. PFDISK has no boot
- program built-in, but allows you to take the boot program
- from a file. At least one of the boot program files, such as
- BOOTMENU, must be available to PFDISK if it is expected to
- initialize a newly formatted disk. Unlike MSDOS fdisk,
- PFDISK correctly handles partition entries which extend
- beyond cyl 1023. Unlike UNIX fdisk, PFDISK is not confused
- about the difference between highest-usable-cylinder-number
- and (beginning-cylinder plus number-of-cylinders).
-
- Documentation included:
-
- The file bootmenu.doc explains how to install and use the new
- boot programs. The file pfdisk.man is manual entry in UNIX *roff
- format, and pfdisk.doc is a formatted copy for those without nroff.
-
- How to compile:
-
- To build pfdisk, either edit the Makefile to uncomment the
- appropriate line (i.e. SYS=i386) and type "make", or
- use a make command line like:
- make SYS=i386
- This will just build the pfdisk program and boot sector binaries.
- It will not try to modify the hard disk boot sector.
-
- The boot program binaries are distributed as simple HEX encoded
- text files. The (included) program hex2bin will convert them
- for the benefit of those without the MASM (DOS) assembler.
-
- Related packages (available separately):
-
- The LOSS1024.FIX package contains patches for MSDOS 3.3 to allow use
- of the first 1024 cylinders of a hard disk when the disk controller
- BIOS has installed disk parameters showing more than 1024 cylinders.
- Note that this patch is designed for use on PC/AT compatible disk
- controllers that have a BIOS parameter override feature, such as the
- RLL and ESDI controllers by Adaptec and Western Digital.
-
- The ESIX-BOOT package contains patches to make ESIX (Everex Systems
- SysV/386) boot from an inactive partition. Normally, ESIX will refuse
- to boot unless its partition is marked as active. These patches allow
- one to configure the partition table such that bootmenu will always
- present its boot menu (no partition marked active).
-
- Send e-mail if you are interested in either of the above.
-
- Gordon W. Ross (M/S E095) internet: gwr@linus.mitre.org
- The MITRE Corporation uucp: {decvax|philabs}!linus!gwr
- Burlington Road office phone: 617-271-3205
- Bedford, MA 01730 (U.S.A.)
-
- SHAR_EOF
- if test 3148 -ne "`wc -c < 'README'`"
- then
- echo shar: error transmitting "'README'" '(should have been 3148 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'pfdisk.man'" '(6386 characters)'
- if test -f 'pfdisk.man'
- then
- echo shar: will not over-write existing file "'pfdisk.man'"
- else
- cat << \SHAR_EOF > 'pfdisk.man'
- .TH PFDISK 8 "Oct 1990" "Release 1.3"
- .SH NAME
- pfdisk \- partition fixed disk
- .SH SYNOPSIS
- .B pfdisk
- .I device
- .SH DESCRIPTION
- .LP
- .B pfdisk
- partitions the fixed disk identified as
- .I device
- into (at most) four parts, each of which may
- be independently loaded with an operating system.
- The actual name of
- .I device
- depends on the operating system in use.
- For ESIX (System V/386) the device name is either
- "/dev/rdsk/0s0" or "/dev/rdsk/1s0".
- For Minix, it is "/dev/hd0" or "/dev/hd5".
- For MS-DOS it is a single digit (zero or one).
- .LP
- .B pfdisk
- reads the hard disk partition table from block zero of
- .I device
- into memory and allows the user to examine, modify, or save the
- partition table. A regular file may be used instead of a real
- .I device
- for testing purposes, though the device geometry must be specified
- manually, and some systems will requrire a file-name argument with
- the "R" and "W" commands (DOS, ESIX).
- .LP
- The partition table on
- .I device
- is NOT modified unless the write command (W) is used with no argument.
- .SH USAGE
- .SS Commands
- .LP
- All
- .B pfdisk
- commands consist of a command word followed by optional
- blank-separated command arguments.
- Note that only the first letter of a command word is significant
- (except for "wq" and "q!").
- All command letters are accepted in either upper or lower case.
- Numeric arguments are specified using C syntax.
- Extra arguments are silently ignored.
- .LP
- The commands are:
- .TP
- .B ?
- Prints a command summary (help).
- .TP
- .BI 1 " sys_id first last sys_name"
- Set the partition table entry for part one, using:
- .I sys_id
- as its system ID code,
- .I first
- as the lowest numbered cylinder it uses,
- .I last
- as the highest numbered cylinder it uses, and
- .I sys_name
- (optional) as the system name (in the menu name table).
- .TP
- .BI 2|3|4 " sys-id first last sys-name"
- Similar to
- .B 1
- but sets partition two, three, or four, respectively.
- .TP
- .BI A " number"
- Mark partition
- .I number
- as active (so it will be used for booting). If
- .I number
- is zero, no partition will be active.
- .TP
- .BI G " cylinders heads sectors"
- Inform
- .B pfdisk
- what the geometry of the device is.
- .TP
- .B I
- Print a summary of the known ID codes.
- .TP
- .B L
- List the partition table.
- See
- .B "Output Format"
- below.
- .TP
- .B Q
- Quit without saving. If the memory copy of the partition table was
- modified, a warning will be issued and the command ignored.
- .TP
- .B Q!
- Quit, even if the memory copy of the partition table was not saved.
- .TP
- .BI R " file-name"
- Read boot sector from
- .I file-name
- (if given) otherwise read from
- .I device.
- .TP
- .BI W " file-name"
- Write boot sector to
- .I file-name.
- (if given) otherwise write to
- .I device.
- .TP
- .B WQ
- Same as "write" followed by "quit".
- .TP
- .B #
- This line is a comment (to be ignored).
- .SS "Output Format"
- .LP
- Here is a sample of the output from the
- .B L
- command:
- .LP
- .nf
- # Partition table on device: /dev/rdsk/0s0
- geometry 1222 15 34 (cyls heads sectors)
- # ID First(cyl) Last(cyl) Name # start, length (sectors)
- 1 4 0 127 MS-LOSS # 34, 65246
- 2 129 128 255 Minix # 65280, 65280
- 3 0 0 0 # 0, 0
- 4 99 256 1220 ESIX # 130560, 492150
- # note: last(4): phys=(1023,14,34) logical=(1220,14,34)
- active: 4
- .fi
- .LP
- This output format is carefully constructed so that it
- may be saved in a file (by redirecting standard output)
- and later used as input (by redirecting standard input).
- On a UNIX system, one can save this output using the command:
- .IP
- (echo L) | pfdisk device-name >
- .I save-file
- .LP The printable representation saved in
- .I save-file
- is a complete record of the partition table.
- On a UNIX system, one could use
- .I save-file
- to re-initialize the partition table using the command:
- .IP
- (cat save-file ; echo wq) | pfdisk device-name
- .LP
- Consistency of each partition table entry is checked
- while the table is listed. Any inconsistencies discovered
- are reported in a commentary note as shown above.
- .SS "Physical vs. Logical"
- .LP
- Each partition table entry has both "physical" and a "logical" fields.
- The physical fields specify the lowest and highest cylinder,head,sector
- combinations to be used in that partition. The logical start field
- has the total number of sectors which precede this partition, and
- the logical length field has the total number of sectors contained
- in this partition. These fields should be self consistent unless
- the disk has more than 1024 cylinders.
- .LP
- The physical cylinder fields are only ten-bits wide so the contents
- are limited to 1023. The logical sector fields are 32 bits wide and
- always show the true logical beginning and length of the partition.
- Generally, the physical start field is used only to locate the
- secondary boot sector, and the logical start and length fields are
- used to actually delimit the partition used by a particular system.
- .SS "Partition Names"
- .LP
- The
- .B Name
- field in the partition table is treated specially if the
- .B bootmenu
- program is installed in the primary boot sector.
- (See the file bootmenu.doc for more information.)
- .B pfdisk
- can recognize the name table used by
- .B bootmenu
- and will show the actual names present in that name table.
- If any other boot program is used then the
- .B Name
- field reflects the result of a table-lookup of the system ID.
- .LP
- If you provide a name when setting any partition entry, the
- boot-sector is marked as using a name table, so that on
- subsequent uses of
- .B pfdisk
- you will see the partition names you have specified.
- .SS "Boot program replacement"
- .LP
- You can replace the boot program in your boot sector without
- affecting the partition table by using
- .B pfdisk
- as follows. First, (as always) save a copy of the current boot
- sector (on a floppy) using the "W file" command. Then, use the
- "R file" command to read the new boot program.
- If the boot program read in is less than 446 bytes long, the
- partition table will be unchanged.
- .LP
- Unlike the DOS or UNIX
- .B fdisk
- programs,
- .B pfdisk
- has
- .I NO
- boot program compiled into its executable image.
- If you wish to use
- .B pfdisk
- to partition a newly formatted hard disk, you must have a boot program
- image available to read in using the "r file" command.
- Two boot programs, "bootmenu.bin" and "bootauto.bin" are distributed with
- .B pfdisk
- and should be found with its source files. See the file bootmenu.doc
- for further information about these boot programs.
- .SH AUTHOR
- Gordon W. Ross
- SHAR_EOF
- if test 6386 -ne "`wc -c < 'pfdisk.man'`"
- then
- echo shar: error transmitting "'pfdisk.man'" '(should have been 6386 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'Changes'" '(1131 characters)'
- if test -f 'Changes'
- then
- echo shar: will not over-write existing file "'Changes'"
- else
- cat << \SHAR_EOF > 'Changes'
- New in version 1.3:
- Oct 90
- Updated documentation for comp.sources.misc posting.
- Cleaned up slightly, using unsigned where appropriate.
- Forced "small" model for MicroSoft C compiler. (DOS...)
- pfdisk command letters can be upper or lower case
- Added partition ID codes as (generously) reported by
- leendert@cs.vu.nl (Leendert van Doorn)
-
- New in version 1.2:
- Sept '90
- Added new, smaller version of boot program (BOOTMENU).
- Renamed boot-hdp to BOOTAUTO (more descriptive of its function?)
- Added prompt (people were confused wihout it)
- Made pfdisk show real name field with sysid==0.
- Made pfdisk set the signature whenever a (1,2,3,4) command
- specifies the optional name argument.
- Made pfdisk complain about invalid boot sector and mark it valid.
-
- New in version 1.1:
- Feb '90
- Added MSDOS compatibility to hex2bin.c
- Moved ESIX patches into a separate package.
-
- Renamed s_minix.c to s_unix.c (it's generic)
- Created an s_isc.c for Interactive Systems UNIX
-
- Fixed inconsistencies in esix-fix.sh and
- Removed byte-order dependencies from pfdisk.c
-
- Revised instructions in boot-hdp.doc
-
- Version 1.0 released (initial beta)
- SHAR_EOF
- if test 1131 -ne "`wc -c < 'Changes'`"
- then
- echo shar: error transmitting "'Changes'" '(should have been 1131 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'Makefile'" '(1629 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- # This makefile supports all UNIX-like systems.
- # Uncomment one of the SYS definitions below, or
- # use a make command like:
- # make SYS=esix
- # (For compiling on MS-DOS, see make_msc.bat)
- # (To compile on Minix, use: make minix)
- #
- # Uncomment for ESIX Sys.V/386 Rel. 3.2
- #SYS=esix
- # Uncomment for other Sys.V/386 systems (ISC,SCO,Intel...)
- #SYS=i386
- # Uncomment for MSDOS with UNIX-style make (i.e. ndmake)
- #SYS=msdos
- # Uncomment for other UNIX-like systems
- SYS=unix
-
- # Compilation options:
- CC=cc
- CFLAGS=-g
-
- FILES1= README pfdisk.man Changes Makefile pfdisk.c syscodes.c \
- syscodes.h sysdep.h s_esix.c s_i386.c s_unix.c s_msdos.c
- FILES2= bootmenu.doc pfdisk.doc SStor.txt bootmenu.asm bootauto.asm \
- asm2bin.bat make_msc.bat bootmenu.hex bootauto.hex hex2bin.c
-
- OBJS= pfdisk.o syscodes.o s_$(SYS).o
- LSRC= pfdisk.c syscodes.c s_$(SYS).c
-
- test: pfdisk
- (echo "g 1222 15 34";\
- echo "1 4 0 127 MS-LOSS";\
- echo "4 99 128 1221 ESIX";\
- echo "a 4"; echo l; echo wq \
- ) | pfdisk /dev/null
-
- all: pfdisk bootmenu.bin bootauto.bin
-
- pfdisk: $(OBJS)
- $(CC) $(CFLAGS) -o $@ $(OBJS)
-
- minix: bootmenu.bin bootauto.bin
- $(CC) $(CFLAGS) -o pfdisk $(LSRC)
-
- pfdisk.o : syscodes.h sysdep.h
- syscodes.o : syscodes.h
- s_$(SYS).o : sysdep.h
-
- lint: $(LSRC)
- lint $(CFLAGS) $(LSRC)
-
- bootmenu.bin: hex2bin
- hex2bin <bootmenu.hex >bootmenu.bin
- bootauto.bin: hex2bin
- hex2bin <bootauto.hex >bootauto.bin
-
- pfdisk.doc: pfdisk.man
- nroff tmac.an pfdisk.man |col -bh >pfdisk.doc
-
- clean:
- rm -f *.o
-
- Shar1.out: Head1.txt $(FILES1)
- (cat Head1.txt ; shar -v -c $(FILES1)) > $@
- Shar2.out: Head2.txt $(FILES2)
- (cat Head2.txt ; shar -v -c $(FILES2)) > $@
-
- SHAR_EOF
- if test 1629 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 1629 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'pfdisk.c'" '(15690 characters)'
- if test -f 'pfdisk.c'
- then
- echo shar: will not over-write existing file "'pfdisk.c'"
- else
- cat << \SHAR_EOF > 'pfdisk.c'
- /*
- * pfdisk - Partition a Fixed DISK
- * by Gordon W. Ross, Jan. 1990
- *
- * See the file "pfdisk.doc" for user instructions.
- *
- * This program uses a simple, line-oriented interpreter,
- * designed for both interactive and non-interactive use.
- * To facilitate non-interactive use, the output from the
- * 'L' (list partitions) command is carefully arranged so it
- * can be used directly as command input. Neat trick, eh?
- */
-
- char *versionString =
- "# pfdisk version 1.2 by Gordon W. Ross Aug. 1990\n";
-
- /* These don't really matter. The user is asked to set them. */
- #define DEFAULT_CYLS 306
- #define DEFAULT_HEADS 4
- #define DEFAULT_SECTORS 17
- #define PROMPT_STRING "pfdisk> "
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include "sysdep.h"
- #include "syscodes.h"
-
- typedef unsigned char uchar;
- typedef unsigned int uint;
- typedef unsigned long ulong;
-
- struct part { /* An entry in the partition table */
- uchar active; /* active flag (0x80 or 0) */
- uchar b_head; /* begin head */
- uchar b_sec; /* sector */
- uchar b_cyl; /* cylinder */
- uchar sysid; /* system id (see sysid.c) */
- uchar e_head; /* end head */
- uchar e_sec; /* end sector */
- uchar e_cyl; /* end cylinder */
- /* These two are just longs, but this way is machine independent. */
- uchar lsBeg[4]; /* logical sectors, beginning */
- uchar lsLen[4]; /* logical sectors, length */
- };
-
- #define LOC_PT 0x1BE
- #define LOC_NT 0x180
- #define LOC_GWR 0x1A0
- #define MAGIC_LOC 0x1FE
- #define MAGIC_0 0x55
- #define MAGIC_1 0xAA
- #define MAX_LINE 80
-
- char buffer[SECSIZE]; /* The boot block buffer */
- int bufmod=0; /* buffer modified... */
- /* (zero means buffer is unmodified) */
- int useNTable; /* boot sector uses name table */
-
- /* device parameters (force someone to set them!) */
- unsigned cyls = DEFAULT_CYLS;
- unsigned heads = DEFAULT_HEADS;
- unsigned sectors = DEFAULT_SECTORS;
-
- char *devname; /* device name */
- char cmdline[MAX_LINE];
- char filename[80]; /* used by r/w commands */
- char *prompt; /* null if no tty input */
-
- /* Some of these strings are used in more than one place.
- * For consistency, I put a newline on all of them.
- */
- char h_h[] = "? <enter> : Help summary\n";
- char h_l[] = "L : List partition table\n";
- char h_1[] = "1 id first last name : set partition 1\n";
- char h_2[] = "2,3,4 ... (like 1) : set respective partition\n";
- char h_a[] = "A n : Activate partition n\n";
- char h_g[] = "G cyls heads sectors : set disk Geometry\n";
- char h_i[] = "I : list known ID numbers\n";
- char h_r[] = "R [optional-file] : Read device (or specified file)\n";
- char h_w[] = "W [optional-file] : Write device (or specified file)\n";
- char h_q[] = "Q[!] : Quit (! means force)\n";
-
- char * helpTable[] = {
- h_h, h_l, h_1, h_2, h_a, h_g, h_i, h_r, h_w, h_q,
- "# (All command letters have lower-case equivalents.)\n",
- (char *) 0 }; /* This MUST have a zero as the last element */
-
- char *BadArg="Error: bad argument: %s\n";
- char *WarnNotSaved =
- "Warning, modified partition table not saved.\n";
-
- help()
- {
- char ** p;
- for (p = helpTable; *p; p++)
- printf(*p);
- }
-
- /* forward declarations */
- void checkValidity();
- char * setPartition();
- char * makeActive();
- char * setGeometry();
- ulong chs2long();
- char * nameID();
- int printIDs();
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- char *cmdp; /* points to command word */
- char *argp; /* points to command args */
-
- /* check command line args (device name) */
- if (argc != 2) {
- usage(argv[0]); /* See s-sysname.c */
- exit(1);
- }
- devname = argv[1];
-
- /* Should we prompt? */
- prompt = (isatty(fileno(stdin))) ? PROMPT_STRING : (char *) 0;
-
- /* Print version name. */
- fputs(versionString, stderr);
-
- /* get disk parameters */
- getGeometry(devname,&cyls,&heads,§ors);
-
- /* Get the boot block. */
- if (getBBlk(devname, buffer) < 0)
- fprintf(stderr,"%s: read failed\n", devname);
- checkValidity();
-
- if (prompt) fprintf(stderr,"For help, enter: '?'\n");
-
-
- /* Read and process commands a line at a time. */
- while (1) {
- if (prompt) fputs(prompt,stdout);
- if (! fgets(cmdline, MAX_LINE, stdin)) break;
-
- /* Find beginning of command word */
- cmdp = cmdline;
- while (isspace(*cmdp)) cmdp++;
-
- /* find beginning of args */
- argp = cmdp;
- while (*argp && !isspace(*argp)) argp++;
- while (isspace(*argp) || *argp=='=') argp++;
-
- switch (*cmdp) {
-
- case '\0': /* blank line */
- case '#': /* line comment */
- break;
-
- case '?': case 'h': case 'H':
- help();
- break;
-
- case '1': /* set partition entry */
- case '2': case '3': case '4':
- argp = setPartition(cmdp, argp);
- if (argp) { /* arg list error */
- fprintf(stderr,BadArg,argp);
- fprintf(stderr,h_1);
- fprintf(stderr,h_2);
- break;
- }
- bufmod = 1;
- break;
-
- case 'a': case 'A': /* activate partition */
- argp = makeActive(argp);
- if (argp) {
- fprintf(stderr,BadArg,argp);
- fprintf(stderr,h_a);
- break;
- }
- bufmod = 1;
- break;
-
- case 'g': case 'G': /* set disk parameters (Geometry) */
- argp = setGeometry(argp);
- if (argp) { /* arg list error */
- fprintf(stderr,BadArg,argp);
- fprintf(stderr,h_g);
- }
- break;
-
- case 'i': case 'I': /* List known ID numbers */
- printIDs();
- break;
-
- case 'l': case 'L': /* List the partition table */
- listPTable();
- break;
-
- case 'q': case 'Q': /* Quit */
- if (bufmod && (cmdp[1] != '!')) {
- fprintf(stderr,"\007%s%s\n", WarnNotSaved,
- "Use 'wq' or 'q!' (enter ? for help).");
- break;
- }
- exit(0);
- /*NOTREACHED*/
-
- case 'r': case 'R': /* read from device or file */
- if (sscanf(argp,"%80s",filename) == 1) {
- /* Arg specified, read from filename */
- if (getFile(filename, buffer, SECSIZE) < 0)
- fprintf(stderr,"%s: read failed\n", filename);
- bufmod = 1;
- } else {
- /* No arg, use device. */
- if (getBBlk(devname, buffer) < 0)
- fprintf(stderr,"%s: read failed\n", devname);
- bufmod = 0;
- }
- checkValidity();
- break;
-
- case 'w': case 'W': /* Write to file or device */
- if (sscanf(argp,"%80s",filename) == 1) {
- /* Arg specified, write to filename */
- if (putFile(filename, buffer, SECSIZE) < 0)
- fprintf(stderr, "%s: write failed\n", filename);
- } else { /* No arg, use device. */
- if (putBBlk(devname, buffer) < 0)
- fprintf(stderr, "%s: write failed\n", devname);
- bufmod = 0;
- }
- if (cmdp[1] == 'q' || cmdp[1] == 'Q') exit(0);
- break;
-
- default:
- fprintf(stderr,"'%c': unrecognized. Enter '?' for help.\n", *cmdp);
- break;
-
- } /* switch */
- } /* while */
- if (bufmod) fprintf(stderr, WarnNotSaved);
- exit(0);
- } /* main */
-
-
- /* Check for valid boot block (magic number in last two bytes).
- * Also, check for presence of partition name table.
- */
- void checkValidity()
- {
- /* Check the magic number. */
- if ((buffer[MAGIC_LOC] & 0xFF) != MAGIC_0 ||
- (buffer[MAGIC_LOC+1] & 0xFF) != MAGIC_1 ) {
- /* The boot sector is not valid -- Fix it. */
- buffer[MAGIC_LOC] = MAGIC_0;
- buffer[MAGIC_LOC+1] = MAGIC_1;
- bufmod = 1;
- fprintf(stderr,
- "\n\tWarning: The boot sector has an invalid magic number.\n\
- \tThe magic number has been fixed, but the other contents\n\
- \tare probably garbage. Initialize using the command:\n\
- \t\tR boot-program-file (i.e. bootmenu.bin)\n\
- \tthen set each partition entry if necessary.\n");
- }
-
- /* Does it use a name table (for a boot menu)?
- * My boot program does, and can be identified by
- * finding my name in a particular (unused) area.
- */
- useNTable = !strcmp(&buffer[LOC_GWR], "Gordon W. Ross");
-
- }
-
- char * setPartition(cmdp,argp) /* return string on error */
- char *cmdp,*argp;
- {
- struct part *pp; /* partition entry */
- char * np; /* name table pointer */
- char * newname; /* name field */
- int index; /* partition index (0..3) */
- uint id; /* ID code (see syscodes.c) */
- uint first,last; /* user supplied cylinders */
- uint c,h,s; /* working cyl,head,sect, */
- uint len; /* chars seen by sscanf */
- ulong lsbeg, lslen; /* logical begin, length */
-
- /* Value check the index */
- index = *cmdp - '1';
- if (index < 0 || index > 3)
- return("index");
- pp = (struct part *) &buffer[LOC_PT + index * 16];
- np = &buffer[LOC_NT + index * 8];
-
- /* Read System ID */
- if (sscanf(argp,"%i%n", &id, &len) < 1)
- return("id");
- argp += len;
-
- /* If ID==0, just clear out the entry and return. */
- if (id == 0) {
- strncpy( (char *) pp, "", 16);
- if (useNTable) strncpy( np, "", 8);
- return((char *)0);
- }
-
- /* Read first and last cylinder */
- if (sscanf(argp,"%i%i%n",&first, &last, &len) < 2)
- return("first last (missing)");
- argp += len;
-
- /* Reasonable start,end cylinder numbers? */
- if (first > last) return("first > last");
- if (first > 1023) return("first > 1023");
- if (last >= cyls) return("last >= cyls");
-
- /* Get (optional) system name. */
- if (*argp == '\n') { /* no name given, use default */
- newname = nameID(id);
- } else { /* use the given name */
- /* skip leading space */
- while (*argp == ' ') argp++;
- newname = argp;
- /* Remove newline from end */
- while (isgraph(*argp)||*argp==' ') argp++;
- *argp = '\0';
- useNTable = 1;
- }
-
- /* Set the ID and name. */
- pp->sysid = id;
- if (useNTable) {
- strncpy(np, newname, 8);
- strcpy(&buffer[LOC_GWR], "Gordon W. Ross");
- }
-
- /* set beginning c,h,s */
- c = first;
- /* if c == 0, head == 1 (reserve track 0) */
- h = (first) ? 0 : 1;
- s = 1;
- pp->b_cyl = c & 0xFF;
- pp->b_head = h;
- pp->b_sec = s | ((c >> 2) & 0xC0);
- /* Set the logical sector begin field */
- lsbeg = lslen = chs2long(c,h,s); /* using lslen as temp. */
- pp->lsBeg[0] = lslen & 0xff; lslen >>= 8;
- pp->lsBeg[1] = lslen & 0xff; lslen >>= 8;
- pp->lsBeg[2] = lslen & 0xff; lslen >>= 8;
- pp->lsBeg[3] = lslen & 0xff; lslen >>= 8;
-
- /* set ending c,h,s (last may be larger than 1023) */
- c = (last>1023) ? 1023 : last; /* limit c to 1023 */
- h = heads - 1; s = sectors;
- pp->e_cyl = c & 0xFF;
- pp->e_head = h;
- pp->e_sec = s | ((c >> 2) & 0xC0);
- /* Set the logical sector length field (using REAL end cylinder) */
- lslen = chs2long(last,h,s) + 1 - lsbeg;
- pp->lsLen[0] = lslen & 0xff; lslen >>= 8;
- pp->lsLen[1] = lslen & 0xff; lslen >>= 8;
- pp->lsLen[2] = lslen & 0xff; lslen >>= 8;
- pp->lsLen[3] = lslen & 0xff; lslen >>= 8;
-
- return((char *)0); /* success */
- } /* setPartition() */
-
- char * makeActive(argp) /* return error string or zero */
- char *argp;
- {
- struct part *pp; /* partition entry */
- int i,act; /* which one becomes active */
-
- if (sscanf(argp,"%d", &act) < 1)
- return("missing index");
- act--; /* make it zero-origin */
-
- i=0; pp = (struct part *) &buffer[LOC_PT];
- while (i<4) {
- pp->active = 0;
- if (i == act) {
- if (pp->sysid == 0) return("partition empty");
- pp->active = 0x80;
- }
- i++; pp++;
- }
- return((char *)0);
- }
-
- char * setGeometry(argp) /* return string on error */
- char *argp;
- {
- int c,h,s;
-
- if (sscanf(argp,"%i%i%i", &c, &h, &s) < 3)
- return("(missing)");
- if (c<1) return("cyls");
- if (h<1) return("heads");
- if (s<1) return("sectors");
- cyls=c; heads=h; sectors=s;
- return((char *)0);
- }
-
- listPTable() /* print out partition table */
- {
- struct part * pp; /* partition table entry */
- char *name;
- int i; /* partition number */
- int numActive=0; /* active partition [1-4], 0==none */
- uint pbc,pbh,pbs; /* physical beginning c,h,s */
- uint pec,peh,pes; /* physical ending c,h,s */
- uint lbc,lbh,lbs; /* logical beginning c,h,s */
- uint lec,leh,les; /* logical ending c,h,s */
- ulong lsbeg,lslen; /* logical sectors: begin, length */
-
- printf("# Partition table on device: %s\n", devname);
- printf("geometry %d %d %d (cyls heads sectors)\n",
- cyls, heads, sectors);
- printf("# ID First(cyl) Last(cyl) Name ");
- printf("# start, length (sectors)\n");
-
- for (i=0; i<4; i++) {
- pp = (struct part *) &buffer[LOC_PT + i * 16];
-
- if (pp->active) {
- if(numActive)
- fprintf(stderr,"Error: multiple active partitions.\n");
- else numActive = i+1;
- }
-
- /* physical beginning c,h,s */
- pbc = pp->b_cyl & 0xff | (pp->b_sec << 2) & 0x300;
- pbh = pp->b_head;
- pbs = pp->b_sec & 0x3F;
-
- /* physical ending c,h,s */
- pec = pp->e_cyl & 0xff | (pp->e_sec << 2) & 0x300;
- peh = pp->e_head;
- pes = pp->e_sec & 0x3F;
-
- /* compute logical beginning (c,h,s) */
- lsbeg = ((((((pp->lsBeg[3] ) << 8 )
- | pp->lsBeg[2] ) << 8 )
- | pp->lsBeg[1] ) << 8 )
- | pp->lsBeg[0] ;
- long2chs(lsbeg, &lbc, &lbh, &lbs);
- /* compute logical ending (c,h,s) */
- lslen = ((((((pp->lsLen[3]) << 8 )
- | pp->lsLen[2]) << 8 )
- | pp->lsLen[1]) << 8 )
- | pp->lsLen[0] ;
- /* keep beginning <= end ... */
- if (lslen > 0) long2chs(lsbeg+lslen-1, &lec, &leh, &les);
- else long2chs(lsbeg, &lec, &leh, &les);
-
- if (useNTable)
- name = &buffer[LOC_NT + i * 8];
- else
- name = nameID((uint) pp->sysid);
-
- /* show physical begin, logical end (works for cyl>1023) */
- /* # ID First(cyl) Last(cyl) Name... # ... */
- printf("%d %3d %4d %4d %-8.8s # %ld, %ld\n",
- i+1, pp->sysid, pbc, lec, name, lsbeg, lslen );
-
- /* That's all, for an empty partition. */
- if (pp->sysid == 0) continue;
-
- /*
- * Now do some consistency checks...
- */
-
- /* Same physical / logical beginning? */
- if (pbc != lbc || pbh != lbh || pbs != lbs ) {
- printf("# note: first(%d): ", i+1);
- printf("phys=(%d,%d,%d) ", pbc, pbh, pbs);
- printf("logical=(%d,%d,%d)\n",lbc, lbh, lbs);
- }
- /* Same physical / logical ending? */
- if (pec != lec || peh != leh || pes != les ) {
- printf("# note: last(%d): ", i+1);
- printf("phys=(%d,%d,%d) ", pec, peh, pes);
- printf("logical=(%d,%d,%d)\n",lec, leh, les);
- }
-
- /* Beginning on cylinder boundary? */
- if (pbc == 0) { /* exception: start on head 1 */
- if (pbh != 1 || pbs != 1) {
- printf("# note: first(%i): ", i+1);
- printf("phys=(%d,%d,%d) ", pbc, pbh, pbs);
- printf("should be (%d,1,1)\n", pbc);
- }
- } else { /* not on cyl 0 */
- if (pbh != 0 || pbs != 1) {
- printf("# note: first(%i): ", i+1);
- printf("phys=(%d,%d,%d) ", pbc, pbh, pbs);
- printf("should be (%d,0,1)\n", pbc);
- }
- }
-
- /* Ending on cylinder boundary? */
- if (peh != (heads-1) || pes != sectors) {
- printf("# note: last(%i): ", i+1);
- printf("phys=(%d,%d,%d) ", pec, peh, pes);
- printf("should be (%d,%d,%d)\n",
- pec, heads-1, sectors);
- }
-
- } /* for */
- printf("active: %d %s\n", numActive,
- (numActive) ? "" : "(none)");
- } /* listPTable() */
-
- ulong chs2long(c,h,s)
- uint c,h,s;
- {
- ulong l;
- if (s<1) s=1;
- l = c; l *= heads;
- l += h; l *= sectors;
- l += (s - 1);
- return(l);
- }
-
- long2chs(ls, c, h, s) /* convert logical sec-num to c,h,s */
- ulong ls; /* Logical Sector number */
- uint *c,*h,*s; /* cyl, head, sector */
- {
- int spc = heads * sectors;
- *c = ls / spc;
- ls = ls % spc;
- *h = ls / sectors;
- *s = ls % sectors + 1; /* sectors count from 1 */
- }
-
- char * nameID(n)
- unsigned int n;
- {
- struct intString *is;
-
- is = sysCodes;
- while (is->i) {
- if (is->i == n) return(is->s);
- is++;
- }
- if (!n) return(is->s);
- return("unknown");
- }
-
- int printIDs() /* print the known system IDs */
- {
- struct intString * is = sysCodes;
-
- /* This might need to do more processing eventually, i.e.
- * if (prompt) { ... do more processing ... }
- */
- printf("_ID_\t__Name__ ____Description____\n");
- while (is->i) {
- printf("%3d\t%s\n", is->i, is->s);
- is++;
- }
- }
- SHAR_EOF
- if test 15690 -ne "`wc -c < 'pfdisk.c'`"
- then
- echo shar: error transmitting "'pfdisk.c'" '(should have been 15690 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'syscodes.c'" '(1357 characters)'
- if test -f 'syscodes.c'
- then
- echo shar: will not over-write existing file "'syscodes.c'"
- else
- cat << \SHAR_EOF > 'syscodes.c'
- /* This file holds all knowledge of partition ID codes.
- * Thanks to leendert@cs.vu.nl (Leendert van Doorn) for
- * collecting most of this information.
- */
-
- #define extern
- #include "syscodes.h"
- #undef extern
-
- /* Note that my boot program menu can only use the first 8 characters
- * of these names. The colon in the nineth position shows where the
- * first truncated char is. (There's not much room in the bootblock!)
- */
- struct intString sysCodes[] = {
- { 0x01, "DOS-12 :12-bit FAT" },
- { 0x02, "XENIX :root" },
- { 0x03, "XENIX :usr" },
- { 0x04, "DOS-16 :16-bit FAT" },
- { 0x05, "DOS-ext :DOS 3.3 extended volume" },
- { 0x06, "DOS-big :DOS 4.0 large volume" },
- { 0x07, "OS/2 :OS/2 (or QNX or Adv. UNIX...)" },
- { 0x08, "AIX :file system" },
- { 0x09, "AIX-boot:boot partition" },
-
- { 0x10, "OPUS :?" },
- { 0x40, "VENIX :Venix 80286" },
- { 0x51, "NOVELL :?" },
- { 0x52, "CPM :?" },
- { 0x63, "UNIX :System V/386" },
- { 0x64, "NOVELL :?" },
- { 0x75, "PC/IX :?" },
- { 0x80, "Minix :Minix (ver. 1.4a and earlier)" },
- { 0x81, "Minix :Minix (ver. 1.4b and later)" },
- { 0x93, "Amoeba :Amoeba file system" },
- { 0x94, "Amoeba :Amoeba bad block table?" },
- { 0xDB, "C.DOS :Concurrent DOS" },
-
- /* { 0xF2, "DOS-2nd :DOS 3.3+ second partition" }, */
- /* { 0xFF, "BAD-TRK :Bad track table?" }, */
-
- /* Make sure this is last! */
- { 0, "(empty)" }
- };
- SHAR_EOF
- if test 1357 -ne "`wc -c < 'syscodes.c'`"
- then
- echo shar: error transmitting "'syscodes.c'" '(should have been 1357 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'syscodes.h'" '(84 characters)'
- if test -f 'syscodes.h'
- then
- echo shar: will not over-write existing file "'syscodes.h'"
- else
- cat << \SHAR_EOF > 'syscodes.h'
- struct intString { unsigned int i; char * s; };
- extern struct intString sysCodes[];
- SHAR_EOF
- if test 84 -ne "`wc -c < 'syscodes.h'`"
- then
- echo shar: error transmitting "'syscodes.h'" '(should have been 84 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'sysdep.h'" '(675 characters)'
- if test -f 'sysdep.h'
- then
- echo shar: will not over-write existing file "'sysdep.h'"
- else
- cat << \SHAR_EOF > 'sysdep.h'
- /* communicate declarations from the files: s_*.c */
-
- #define SECSIZE 0x200
-
- extern int usage(); /* print a usage message */
- /* (char *progname) */
-
- extern void getGeometry(); /* determine disk parameters */
- /* (char *dev, uint *cyls, uint *heads, uint *sectors) */
-
- extern int getFile(); /* open, read, close, return(num-read) */
- /* (char *name, char *buf, int len) */
-
- extern int putFile(); /* open, write, close, return(num-writen) */
- /* (char *name, char *buf, int len) */
-
- extern int getBBlk(); /* open, read, close, return(num-read) */
- /* (char *dev, char *buf) */
-
- extern int putBBlk(); /* open, write, close, return(num-writen) */
- /* (char *dev, char *buf) */
- SHAR_EOF
- if test 675 -ne "`wc -c < 'sysdep.h'`"
- then
- echo shar: error transmitting "'sysdep.h'" '(should have been 675 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'s_esix.c'" '(3085 characters)'
- if test -f 's_esix.c'
- then
- echo shar: will not over-write existing file "'s_esix.c'"
- else
- cat << \SHAR_EOF > 's_esix.c'
- /* This file contains system-specific functions for ESIX.
- * The program pfdisk.c calls these routines.
- * Note that ESIX can't use the generic Sys.V/386 version of
- * this file because it uses ioctl calls to access the
- * primary boot sector. Other systems provide a device which
- * maps onto the whole disk (starting with the boot sector).
- */
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/vtoc.h>
-
- #define extern
- #include "sysdep.h"
- #undef extern
-
- int usage(prog) /* print a usage message */
- char *prog; /* program name */
- {
- fprintf(stderr,"Usage: %s dev\n\t%s\n", prog,
- "where 'dev' is the device name, i.e. /dev/rdsk/0s0");
- }
-
- void getGeometry(dev, c, h, s)
- char *dev; /* device name */
- unsigned *c,*h,*s; /* cyls, heads, sectors */
- {
- int devfd, retval;
- struct disk_parms dp;
-
- devfd = open(dev, O_RDONLY, 0);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for reading\n", dev);
- return;
- }
- retval = ioctl(devfd, V_GETPARMS, &dp);
- close(devfd);
- if (retval < 0) {
- fprintf(stderr,"%s: can't get disk parameters\n", dev);
- return;
- }
- if (dp.dp_type != DPT_WINI) {
- fprintf(stderr,"%s: not a Winchester Disk\n", dev);
- return;
- }
- *c = dp.dp_cyls;
- *h = dp.dp_heads;
- *s = dp.dp_sectors;
- }
-
- int getFile(name, buf, len) /* read file into buffer */
- char *name, *buf;
- int len;
- { /* (open, read, close) */
- int devfd, retval;
-
- devfd = open(name, O_RDONLY, 0);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for reading\n", name);
- return(devfd);
- }
- retval = read(devfd, buf, len);
- if (retval < 0)
- fprintf(stderr,"%s: read failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int putFile(name, buf, len) /* write buffer to file */
- char *name, *buf;
- int len;
- { /* (open, write, close) */
- int devfd, retval;
-
- devfd = open(name, O_WRONLY|O_CREAT, 0666);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for writing\n", name);
- return(devfd);
- }
- retval = write(devfd, buf, len);
- if (retval < 0)
- fprintf(stderr,"%s: write failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int getBBlk(name, buf) /* read Boot Block into buffer */
- char *name, *buf;
- { /* (open, read, close) */
- int devfd, retval;
- struct absio abs;
-
- devfd = open(name, O_RDONLY, 0);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for reading\n", name);
- return(devfd);
- }
- abs.abs_sec = 0; /* the primary boot sector */
- abs.abs_buf = buf;
- retval = ioctl(devfd, V_RDABS, &abs);
- if (retval < 0)
- fprintf(stderr,"%s: read failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int putBBlk(name, buf) /* write buffer to Boot Block */
- char *name, *buf;
- { /* (open, write, close) */
- int devfd, retval;
- struct absio abs;
-
- devfd = open(name, O_WRONLY, 0);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for writing\n", name);
- return(devfd);
- }
- abs.abs_sec = 0; /* the primary boot sector */
- abs.abs_buf = buf;
- retval = ioctl(devfd, V_WRABS, &abs);
- if (retval < 0)
- fprintf(stderr,"%s: write failed\n", name);
- close(devfd);
- return(retval);
- }
- SHAR_EOF
- if test 3085 -ne "`wc -c < 's_esix.c'`"
- then
- echo shar: error transmitting "'s_esix.c'" '(should have been 3085 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'s_i386.c'" '(2647 characters)'
- if test -f 's_i386.c'
- then
- echo shar: will not over-write existing file "'s_i386.c'"
- else
- cat << \SHAR_EOF > 's_i386.c'
- /* This file contains system-specific functions suitable for
- * most AT&T System V/386 variants (ISC,SCO,Intel...).
- * The program pfdisk.c calls these routines.
- */
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/vtoc.h>
-
- #define extern
- #include "sysdep.h"
- #undef extern
-
- int usage(prog) /* print a usage message */
- char *prog; /* program name */
- {
- fprintf(stderr,"Usage: %s dev\n\
- where 'dev' is the device name, i.e. /dev/rdsk/0p0\n\
- (The device must start on absolute sector zero.)\n",prog);
- }
-
- void getGeometry(dev, c, h, s)
- char *dev; /* device name */
- unsigned *c,*h,*s; /* cyls, heads, sectors */
- {
- int devfd, retval;
- struct disk_parms dp;
-
- devfd = open(dev, O_RDONLY, 0);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for reading\n", dev);
- return;
- }
- retval = ioctl(devfd, V_GETPARMS, &dp);
- close(devfd);
- if (retval < 0) {
- fprintf(stderr,"%s: can't get disk parameters\n", dev);
- return;
- }
- if (dp.dp_type != DPT_WINI) {
- fprintf(stderr,"%s: not a Winchester Disk\n", dev);
- return;
- }
- *c = dp.dp_cyls;
- *h = dp.dp_heads;
- *s = dp.dp_sectors;
- }
-
- int getFile(name, buf, len) /* read file into buffer */
- char *name, *buf;
- int len;
- { /* (open, read, close) */
- int devfd, retval;
-
- devfd = open(name, O_RDONLY, 0);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for reading\n", name);
- return(devfd);
- }
- retval = read(devfd, buf, len);
- if (retval < 0)
- fprintf(stderr,"%s: read failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int putFile(name, buf, len) /* write buffer to file */
- char *name, *buf;
- int len;
- { /* (open, write, close) */
- int devfd, retval;
-
- devfd = open(name, O_WRONLY|O_CREAT, 0666);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for writing\n", name);
- return(devfd);
- }
- retval = write(devfd, buf, len);
- if (retval < 0)
- fprintf(stderr,"%s: write failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int getBBlk(devname, buffer) /* read block into buffer */
- char *devname, *buffer; /* (open, read, close) */
- {
- int devfd, retval;
-
- devfd = open(devname,O_RDONLY);
- if (devfd < 0) {
- printf("%s: can't open for read\n", devname);
- return(devfd);
- }
- retval = read(devfd, buffer, SECSIZE);
- close(devfd);
- return(retval);
- }
-
- int putBBlk(devname, buffer) /* write buffer to device */
- char *devname, *buffer; /* (open, write, close) */
- {
- int devfd, retval;
-
- devfd = open(devname,O_WRONLY);
- if (devfd < 0) {
- printf("%s: can't open for write\n",devname);
- return(devfd);
- }
- retval = write(devfd, buffer, SECSIZE);
- sync();
- close(devfd);
- return(retval);
- }
- SHAR_EOF
- if test 2647 -ne "`wc -c < 's_i386.c'`"
- then
- echo shar: error transmitting "'s_i386.c'" '(should have been 2647 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'s_unix.c'" '(2426 characters)'
- if test -f 's_unix.c'
- then
- echo shar: will not over-write existing file "'s_unix.c'"
- else
- cat << \SHAR_EOF > 's_unix.c'
- /* This file contains system-specific functions for generic UNIX.
- * The program pfdisk.c calls these routines.
- */
- #include <stdio.h>
- #include <fcntl.h>
-
- #define extern
- #include "sysdep.h"
- #undef extern
-
- int usage(prog) /* print a usage message */
- char *prog; /* program name */
- {
- fprintf(stderr,"Usage: %s dev\n\
- \twhere 'dev' is the device name, i.e. /dev/hd0\n\
- \t(The device must start on absolute sector zero.)\n",prog);
- }
-
- void getGeometry(dev, c, h, s)
- char *dev; /* device name */
- unsigned *c,*h,*s; /* cyls, heads, sectors */
- {
- fprintf(stderr,
- "\n\tWarning: The device \"%s\" is assumed to have:\n\
- \tcyls=%d, heads=%d, sectors=%d (an arbitrary guess).\n",
- dev, *c, *h, *s);
- fprintf(stderr,
- "\n\tThis program was compiled for generic UNIX and therefore\n\
- \tdoes not know how to determine the disk parameters. You must\n\
- \tdescribe the disk geometry manually, using the 'G' command.\n");
- }
-
- int getFile(name, buf, len) /* read file into buffer */
- char *name, *buf;
- int len;
- { /* (open, read, close) */
- int devfd, retval;
-
- devfd = open(name, O_RDONLY, 0);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for reading\n", name);
- return(devfd);
- }
- retval = read(devfd, buf, len);
- if (retval < 0)
- fprintf(stderr,"%s: read failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int putFile(name, buf, len) /* write buffer to file */
- char *name, *buf;
- int len;
- { /* (open, write, close) */
- int devfd, retval;
-
- devfd = open(name, O_WRONLY|O_CREAT, 0666);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for writing\n", name);
- return(devfd);
- }
- retval = write(devfd, buf, len);
- if (retval < 0)
- fprintf(stderr,"%s: write failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int getBBlk(devname, buffer) /* read block into buffer */
- char *devname, *buffer; /* (open, read, close) */
- {
- int devfd, retval;
-
- devfd = open(devname,O_RDONLY);
- if (devfd < 0) {
- printf("%s: can't open for read\n", devname);
- return(devfd);
- }
- retval = read(devfd, buffer, SECSIZE);
- close(devfd);
- return(retval);
- }
-
- int putBBlk(devname, buffer) /* write buffer to device */
- char *devname, *buffer; /* (open, write, close) */
- {
- int devfd, retval;
-
- devfd = open(devname,O_WRONLY);
- if (devfd < 0) {
- printf("%s: can't open for write\n",devname);
- return(devfd);
- }
- retval = write(devfd, buffer, SECSIZE);
- sync();
- close(devfd);
- return(retval);
- }
- SHAR_EOF
- if test 2426 -ne "`wc -c < 's_unix.c'`"
- then
- echo shar: error transmitting "'s_unix.c'" '(should have been 2426 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'s_msdos.c'" '(3768 characters)'
- if test -f 's_msdos.c'
- then
- echo shar: will not over-write existing file "'s_msdos.c'"
- else
- cat << \SHAR_EOF > 's_msdos.c'
- /* This file contains system-specific functions for MS-DOS.
- * The program pfdisk.c calls these routines.
- */
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <dos.h>
-
- #define extern
- #include "sysdep.h"
- #undef extern
-
- int usage(prog) /* print a usage message */
- char *prog; /* program name */
- {
- fprintf(stderr,"Usage: %s <disk>\n", prog);
- fprintf(stderr,"\twhere <disk> is a digit [0-9]\n");
- }
-
- void getGeometry(name, c, h, s)
- char *name; /* device name */
- unsigned *c,*h,*s; /* cyls, heads, sectors */
- {
- int dev; /* hard disk number */
- union REGS regs;
- struct SREGS sregs;
-
- if (name[0] < '0' ||
- name[0] > '9' ||
- name[1] != 0 )
- {
- fprintf(stderr,"%s: device name must be a digit\n", name);
- return;
- }
- dev = (name[0] - '0');
-
- regs.h.ah = 8; /* get param. */
- regs.h.dl = dev | 0x80;
-
- int86x(0x13,®s,®s,&sregs);
-
- /* Are that many drives responding? */
- if (regs.h.dl <= dev ) {
- fprintf(stderr,"%s: drive not found\n", name);
- return;
- }
- if (regs.x.cflag) {
- fprintf(stderr,"%s: can't get disk parameters\n", name);
- return;
- }
- *c = ((((int) regs.h.cl << 2) & 0x300) | regs.h.ch) + 1;
- *h = regs.h.dh + 1;
- *s = regs.h.cl & 0x3F;
- }
-
- int getFile(name, buf, len) /* read file into buffer */
- char *name, *buf;
- int len;
- { /* (open, read, close) */
- int devfd, retval;
-
- devfd = open(name, O_RDONLY|O_BINARY, 0);
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for reading\n", name);
- return(devfd);
- }
- retval = read(devfd, buf, len);
- if (retval < 0)
- fprintf(stderr,"%s: read failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int putFile(name, buf, len) /* write buffer to file */
- char *name, *buf;
- int len;
- { /* (open, write, close) */
- int devfd, retval;
-
- devfd = open(name,
- O_WRONLY|O_CREAT|O_BINARY,
- S_IREAD|S_IWRITE ); /* stupid DOS... */
- if (devfd < 0) {
- fprintf(stderr,"%s: can't open for writing\n", name);
- return(devfd);
- }
- retval = write(devfd, buf, len);
- if (retval < 0)
- fprintf(stderr,"%s: write failed\n", name);
- close(devfd);
- return(retval);
- }
-
- int getBBlk(name, buf) /* read boot block into buffer */
- char *name, *buf;
- { /* BIOS absolute disk read */
- int dev;
- union REGS regs;
- struct SREGS sregs;
-
- if (name[0] < '0' ||
- name[0] > '9' ||
- name[1] != 0 )
- {
- fprintf(stderr,"%s: device name must be a digit\n",name);
- return(-1);
- }
- dev = (name[0] - '0');
-
- segread(&sregs); /* get ds */
- sregs.es = sregs.ds; /* buffer address */
- regs.x.bx = (int) buf;
-
- regs.h.ah = 2; /* read */
- regs.h.al = 1; /* sector count */
- regs.h.ch = 0; /* track */
- regs.h.cl = 1; /* start sector */
- regs.h.dh = 0; /* head */
- regs.h.dl = dev|0x80; /* drive */
-
- int86x(0x13,®s,®s,&sregs);
- if (regs.x.cflag) {
- fprintf(stderr,"%s: read failed\n", name);
- return(-1);
- }
- return(SECSIZE);
- }
-
- int putBBlk(name, buf) /* write buffer to boot block */
- char *name, *buf;
- { /* BIOS absolute disk write */
- int dev;
- union REGS regs;
- struct SREGS sregs;
-
- if (name[0] < '0' ||
- name[0] > '9' ||
- name[1] != 0 )
- {
- fprintf(stderr,"%s: device name must be a digit\n", name);
- return(-1);
- }
- dev = (name[0] - '0');
-
- segread(&sregs); /* get ds */
- sregs.es = sregs.ds; /* buffer address */
- regs.x.bx = (int) buf;
-
- regs.h.ah = 3; /* write */
- regs.h.al = 1; /* sector count */
- regs.h.ch = 0; /* track */
- regs.h.cl = 1; /* start sector */
- regs.h.dh = 0; /* head */
- regs.h.dl = dev|0x80; /* drive */
-
- int86x(0x13,®s,®s,&sregs);
- if (regs.x.cflag) {
- fprintf(stderr,"%s: write failed\n",name);
- return(-1);
- }
- return(SECSIZE);
- }
- SHAR_EOF
- if test 3768 -ne "`wc -c < 's_msdos.c'`"
- then
- echo shar: error transmitting "'s_msdos.c'" '(should have been 3768 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-